package test;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

/**
 * id = 0 zarezerwowane dla root'a.
 * <dl>
 * <dd> Unikalny id.</dd>
 * <dd>unikalna para parent, name.</dd>
 * </dl>
 * 
 * @author kozerskil
 */
public class Group{

    private int    id;
    private int    parent;
    private String name;

    /**
     * Odczytuje element z bazy.
     * 
     * @param id
     * @throws SQLException
     */
    public Group(int id) throws Exception{
        this.id = id;

        PreparedStatement gr = DBFactory.prepareStatement("select * from "
            + DBFactory.TABLE + " where id = ?");
        gr.setInt(1, id);

        ResultSet rs = gr.executeQuery();
        if(rs.next()){
            this.name = rs.getString("name");
            this.parent = rs.getInt("parent");
        }
        rs.close();
        gr.close();
    }

    /**
     * Zapisuje elemet do bazy.
     * 
     * @param parent
     * @param name
     * @throws SQLException
     */
    public Group(int parent, String name) throws Exception{
        this.parent = parent;
        this.name = name;

        PreparedStatement ins = DBFactory.prepareStatement("insert into "
            + DBFactory.TABLE + " (parent, name) values (?, ?)");
        ins.setInt(1, parent);
        ins.setString(2, name);
        ins.executeUpdate();

        ins = DBFactory.prepareStatement("select id from " + DBFactory.TABLE
            + " where parent = ? and  name = ?");
        ins.setInt(1, parent);
        ins.setString(2, name);
        ResultSet rs = ins.executeQuery();
        if(rs.next()){
            this.id = rs.getInt("id");
        }
        rs.close();
        ins.close();
    }

    /**
     * Update danych w bazie
     * 
     * @throws SQLException
     */
    public void update() throws Exception{
        PreparedStatement ins = DBFactory.prepareStatement("UPDATE "
            + DBFactory.TABLE + " set (parent = ?, name = ?) where id = ?");
        ins.setInt(3, id);
        ins.setInt(1, parent);
        ins.setString(2, name);
        ins.executeUpdate();
    }

    public Group[] getSubGroups() throws Exception{
        PreparedStatement gr = DBFactory.prepareStatement("select id from "
            + DBFactory.TABLE + " where parent = ? order by id");
        gr.setInt(1, id);
        List<Group> l = new LinkedList<Group>();
        ResultSet rs = gr.executeQuery();
        while(rs.next()){
            l.add(new Group(rs.getInt("id")));
        }
        rs.close();
        gr.close();
        return l.toArray(new Group[0]);
    }

    @Override
    public String toString(){
        if(id == 0)
            return "/";

        try{
            return toStr();
        }catch(Exception e){
            return null;
        }
    }

    private String toStr() throws Exception{
        if(id == 0)
            return "";
        return new Group(getParent()).toStr() + "/" + name;
    }

    public static Group getGroup(String path, boolean create)
        throws Exception{

        if(path.charAt(0) != '/')
            return null;

        String[] paths = path.split("/");
        int id = 0;
        for(int i = 1; i < paths.length; i++){
            PreparedStatement gr = DBFactory.prepareStatement("select id from "
                + DBFactory.TABLE + " where parent = ? and name = ?");
            gr.setInt(1, id);
            gr.setString(2, paths[i]);
            ResultSet rs = gr.executeQuery();
            if(rs.next()){
                id = rs.getInt("id");
                rs.close();
            }else{
                rs.close();
                if(!create)
                    return null;
                id = new Group(id, paths[i]).getId();
            }
            gr.close();
        }
        return new Group(id);
    }

    public int getId(){
        return id;
    }

    public String getName(){
        return name;
    }

    public int getParent(){
        return parent;
    }

    public void setId(int id){
        this.id = id;
    }

    public void setParent(int parent){
        this.parent = parent;
    }

    public void setName(String name){
        this.name = name;
    }
}
